package com.lpwa.framework.netty;

import com.lpwa.common.utils.StringConvert;
import com.lpwa.framework.netty.utils.NettyByteAndStringUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.nio.ByteOrder;
import java.nio.charset.Charset;

/**
 * @describe 消息解码器
 * @author zhikai.chen
 * @date 2018年4月28日 上午11:09:15
 */
public class MessageDecoder extends LengthFieldBasedFrameDecoder {
	
    //body(4)+zip(1)+cmdId(2)+type(1)=8
    private static final int HEADER_SIZE = 10;
    
    // 编码格式
 	private final Charset charset = Charset.forName("UTF-8");

    public MessageDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast) {
        super(byteOrder, maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast);
    }


    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        if (in == null) {
            return null;
        }
 
        // 消息头读取不完整，不做解析返回null，直到读完整为止
        if (in.readableBytes() <= HEADER_SIZE) {
            return null;
        }
 
        in.markReaderIndex();
        //body(4)+zip(1)+cmdId(2)+type(1)=8
        byte handle = in.readByte(); //FE头，2
        //Convert back to String
//        byte[] buffer = new byte[1];
//        buffer[0]=handle;
//        String s = new String(buffer,charset);
        System.out.println("handle:"+handle);
        int length = in.readIntLE();//长度，4个字节
//        byte[] lengthbuffer = new byte[length];
//        String lengthData = NettyByteAndStringUtils.byteToHex(lengthbuffer);
//        System.out.println("lengthData:"+lengthData);
        char cmd0 = in.readChar();//cmd0，1个字节
        char cmd1 = in.readChar();//cmd1，1个字节
//        byte type = in.readByte();
//        byte zip = in.readByte();
//        int dataLength = in.readInt();
//        int a = in.readIntLE();
        //小端转大端
        byte[] len = StringConvert.string2Bytes(String.valueOf(length));
        long dataLength = StringConvert.getLong(len,true);
        // TODO 网络信号不好，没有接收到完整数据
        if (in.readableBytes()-1 < length) { //EF(表头)+8900（长度）+00（cmd0）+01（cmd1）+数据域+异或校验（1个字节）
        	//保存当前读到的数据，下一次继续读取
        	//断包处理：查看ByteToMessageDecoder的channelRead方法，ByteBuf cumulation属性
            in.resetReaderIndex();
            return null;
        }
 
        byte[] data = new byte[length+2];
        in.readBytes(data);
        
        // TODO 手动释放内存
        //in.release(); // or ReferenceCountUtil.release(in);
        
        //判断是否压缩
//        if(zip==1){
//        	data=ZipTool.uncompress(data);
//        }
        String body = new String(data, charset);
//        Message msg = new Message(body, cmdId, type);
        return handle+length+cmd0+cmd1+body;
    }
}